package com.xxl.sso.server.controller;

import com.databstech.apis.result.enums.ResultCodeEnum;
import com.databstech.apis.result.response.ResultVO;
import com.xxl.sso.core.login.SsoTokenLoginHelper;
import com.xxl.sso.core.store.SsoLoginStore;
import com.xxl.sso.core.store.SsoSessionIdHelper;
import com.xxl.sso.core.user.XxlSsoUser;
import com.xxl.sso.server.core.model.UserInfo;
import com.xxl.sso.server.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * sso server (for app)
 *
 * @author xuxueli 2018-04-08 21:02:54
 */
@Controller
@RequestMapping("/app")
public class AppController {

    @Autowired
    private UserService userService;


    /**
     * Login
     *
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/login")
    @ResponseBody
    public ResultVO<Map<String, Object>> login(String username, String password) {

        // valid login
            ResultVO<UserInfo> result = userService.findUser(username, password);
        if (result.getCode() != ResultVO.success().getCode()) {
            return ResultVO.fail(result.getCode(), result.getMessage());
        }

        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        xxlUser.setUserid(String.valueOf(result.getData().getUserid()));
        xxlUser.setUsername(result.getData().getUsername());
        xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        xxlUser.setExpireMinute(SsoLoginStore.getRedisExpireMinute());
        xxlUser.setExpireFreshTime(System.currentTimeMillis());


        // 2、generate sessionId + storeKey
        String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);

        // 3、login, store storeKey
        SsoTokenLoginHelper.login(sessionId, xxlUser);

        // 4、return sessionId
        Map<String, Object> returnMap = object2Map(xxlUser);
        returnMap.put("token",sessionId);
        return ResultVO.success(returnMap);
    }


    /**
     * Logout
     *
     * @param token
     * @return
     */
    @RequestMapping("/logout")
    @ResponseBody
    public ResultVO<String> logout(String token) {
        // logout, remove storeKey
        SsoTokenLoginHelper.logout(token);
        return ResultVO.success();
    }

    /**
     * logincheck
     *
     * @param token
     * @return
     */
    @RequestMapping("/logincheck")
    @ResponseBody
    public ResultVO<XxlSsoUser> logincheck(String token) {

        // logout
        XxlSsoUser xxlUser = SsoTokenLoginHelper.loginCheck(token);
        if (xxlUser == null) {
            return ResultVO.fail(ResultCodeEnum.Fail5.getCode(), "sso not login.");
        }
        return ResultVO.success(xxlUser);
    }




    /**
     * 实体对象转成Map
     *
     * @param obj 实体对象
     * @return {Map}
     */
    private static Map<String, Object> object2Map(Object obj) {
        Map<String, Object> map = new HashMap<>();
        if (obj == null) {
            return map;
        }
        Class clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

}
